package juf.ui;

import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JToolBar;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JPanel;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;


import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import juf.ui.JufInstanceList.SortOrders;

//http://java.sun.com/docs/books/tutorial/uiswing/examples/components/ToolBarDemoProject/src/components/ToolBarDemo.java 

/**Provides the layout, contains a JufInstanceList and a JufForm
 * <p/>
 * After creating a JufInterface, call setVisible(true) to show it, as you would a JFrame<br/>
 * <hr/>
 * TODO: <ol>
 * <li>Ability to move stuff around in container - parameters/config file/dragging</li>
 * <li>Validation of components & form before save</li>
 * <li>Annotation to order components on the jufform</li>
 * <li>Exception handling and error reporting</li>
 * <li>Bookmark/history on the toolbar</li>
 * <li>Add new object</li>
 * <li>Filter by form</li>
 * </ol>
 * @author Parul Sharma
 *
 */
@SuppressWarnings("serial")
public class JufInterface<T> extends JFrame implements ActionListener {


    private JufInstanceList<T> instances; //list for selecting instances of type T - use getSelectedObject() for this
    
    private JToolBar toolBar;
    private JScrollPane formScrollPane; //scrolling the jufform
    private JScrollPane listScrollPane; //scrolling the jufinstancelist
    private JufForm form;
    private JPanel panel; //this panel holds all the other components, it alone sits inside this.
    private JComboBox bookmarkBox;
    public final int x, y; //initial dims of the frame
    
    /**Create a new JufInterface
     * 
     * @param ts list of objects to create the interface around
     * @param width TODO
     * @param height TODO
     */
    public JufInterface(java.util.Collection<T> ts, int width, int height) {
    	super("JufInterface");
    	
    	x=width;
    	y=height;
		//set L&F
		try {
			UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName());
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedLookAndFeelException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	
        panel = new JPanel(new BorderLayout());

        //Create the toolbar
        toolBar = new JToolBar("Tool Bar");
        addButtons(toolBar);
      
        //Create the JufInstanceList with whatever type this class has been initialized with
        instances = new JufInstanceList<T>(ts);
        //instances.setPreferredSize(new Dimension(300,600));
        listScrollPane = new JScrollPane(instances); //put it in a scroll pane.
        listScrollPane.setPreferredSize(new Dimension(width/3,height));
        listScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
       
        //Create the form and its scroll pane
        form = new JufForm(ts.toArray()[0]);
        form.setPreferredSize(new Dimension(2*(x/3),y));     
        formScrollPane = new JScrollPane(form);
        
        //set up the MouseListener for doubleclick events, using an anonymous class
		instances.addMouseListener( new MouseAdapter() {
		    public void mouseClicked(MouseEvent e) {
		        if (e.getClickCount() == 2) {
		            changeForm(instances.getSelectedObject());    
		        	System.out.println("Viewing: " + instances.getSelectedObject());
		            //switch out the jufform depending on what instance has been dbl-clicked
		        	//panel.remove(formScrollPane);
		        	JufInterface.this.form = new JufForm(instances.getSelectedObject());  
		        	JufInterface.this.form.setPreferredSize(new Dimension(2*(JufInterface.this.x/3),JufInterface.this.y)); 
		            JufInterface.this.formScrollPane = new JScrollPane(form);
		            panel.add(formScrollPane, BorderLayout.CENTER);
		            //update the interface
		            panel.revalidate();//must call repaint on the parent container
		         }
		    }
		}); 

        //Lay out the main panel.
		panel.add(toolBar, BorderLayout.PAGE_START); //add the toolbar
		panel.add(formScrollPane, BorderLayout.CENTER); //add the form's scroll pane (containing the form)
		panel.add(listScrollPane, BorderLayout.WEST); //and add it to the panel
		
		//set up the JFrame properties of this.
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //set the window close operation to exit
		getContentPane().add(panel); //add the JufForm to the window
		pack();

    }

    

    /** Adds buttons to the toolbar
     * @param toolBar JToolBar to add the buttons to
     */
    protected void addButtons(JToolBar toolBar) {
    	
        ImageIcon sortAZ = new ImageIcon("images/sort_az_icon.gif"); 
        ImageIcon sortZA = new ImageIcon("images/sort_za_icon.gif"); 
        ImageIcon delete = new ImageIcon("images/action_delete.gif"); 
        ImageIcon copy = new ImageIcon("images/foldericon_sml.gif");
//        ImageIcon filter = new ImageIcon("images/foldericon_sml.gif");
        ImageIcon bookmark = new ImageIcon("images/bookmark_icon.gif");
        
        JButton button = null;

        //first button
        button = makeToolsButton(copy, "Copy","Copy the instance", this);
        toolBar.add(button);

        //second button
        button = makeToolsButton(sortAZ, "Sort A-Z", "Sort ascending order", this);
        toolBar.add(button);
        
        //third button
        button = makeToolsButton(sortZA, "Sort Z-A", "Sort descending order", this);
        toolBar.add(button);
        
        button = makeToolsButton(delete, "Delete","Delete the instance", this);
        toolBar.add(button);
        
        button = makeToolsButton(bookmark, "Bookmark","Bookmark form", this);
        toolBar.add(button);
        
        toolBar.add(getBookmarkBox());
        
       
//        button = makeToolsButton(filter, "Filter","Filter form", this);
//        toolBar.add(button);
        
        
    }
    
    
    public JComboBox getBookmarkBox(){
        bookmarkBox = new JComboBox();
        bookmarkBox.setMaximumSize(new Dimension(150,100));
        bookmarkBox.addActionListener(new ActionListener(){
        	@SuppressWarnings("unchecked")
			public void actionPerformed(ActionEvent a){
        		JComboBox cb = (JComboBox)a.getSource();
                T item = (T) cb.getSelectedItem();
                changeForm(item);
                
        	}
        });
        bookmarkBox.addKeyListener(new KeyListener(){
        	@SuppressWarnings("unchecked")
			public void keyPressed(KeyEvent k){
        		JComboBox cb = (JComboBox)k.getSource();
                T item = (T) cb.getSelectedItem();
                int ch = k.getKeyCode();
                if (ch==127){
                	if (bookmarkBox.getItemCount()>0)
                		bookmarkBox.removeItem(item);
                }
        	}

			@Override
			public void keyReleased(KeyEvent e) {				
			}

			@Override
			public void keyTyped(KeyEvent e) {
			}

			
        });
        

        
        return bookmarkBox;
    }
    
    /**
     * given an instance/object this method loads it into the panel
     * @param newForm
     */
    public void changeForm(T newForm){
    	System.out.println("Viewing: " + instances.getSelectedObject());
        //switch out the jufform depending on what instance has been dbl-clicked
    	panel.remove(formScrollPane);
    	if (newForm != null)
    		JufInterface.this.formScrollPane = new JScrollPane(new JufForm(newForm));
    	else 
    		JufInterface.this.formScrollPane = new JScrollPane();
        panel.add(formScrollPane, BorderLayout.CENTER);
        //update the interface
        panel.revalidate();//must call repaint on the parent container
        panel.repaint();	
    	
    }

    /**Generates a standardized toolbar button
     * 
     * @param imageName	Icon to use, if null, no icon
     * @param actionCommand	Command that the listener will listen for
     * @param toolTipText Tooltip text to use
     * @param a ActionListener to handle button click event
     * @return JButton for use in toolbar
     */
    public static JButton makeToolsButton(ImageIcon imageName, String actionCommand, String toolTipText, ActionListener a) {
    
        //Create and initialize the button.
        JButton button = new JButton();
        button.setActionCommand(actionCommand);
        button.setToolTipText(toolTipText);
        button.addActionListener(a);
        
        button.setText(actionCommand);
        //button.setIconTextGap(6);
        if (imageName != null) button.setIcon(imageName);
        return button;
    }

    /** Listens to the button-click events
     * 
     * (non-Javadoc)
     * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
     */
    public void actionPerformed(ActionEvent e) {
        
    	String cmd = e.getActionCommand();


        // Handle each button.
        //get the instance selected
        //then clone that instance and make the juf instance list return that instance
        
        if ("Copy".equals(cmd) && instances.getSelectedIndex() >= 0) { //first button clicked & object is selected

            T copy = instances.getCopy();
            if (copy != null)
            	instances.add(copy);
            instances.refresh();
            
            
        } else if ("Sort A-Z".equals(cmd)) { // second button clicked
        	//calls the refresh method of instance list and passes a sort param
			instances.refresh(SortOrders.ASCENDING);
       	

        } else if ("Sort Z-A".equals(cmd)) { // third button clicked
        	//calls the refresh method of instance list and passes a sort param
			instances.refresh(SortOrders.DESCENDING);

        }
        else if ("Delete".equals(cmd) && instances.getSelectedIndex() >= 0) { // third button clicked & object selected
	    	//calls the refresh method of instance list and passes a sort param
			instances.remove(instances.getSelectedIndex());
			instances.refresh();
	        //switch out the jufform depending on what instance has been dbl-clicked
	    	panel.remove(formScrollPane);
	        JufInterface.this.formScrollPane = new JScrollPane();
	        panel.add(formScrollPane, BorderLayout.CENTER);
	        //update the interface
	        panel.revalidate();//must call repaint on the parent container
	        panel.repaint();

        }
        else if ("Bookmark".equals(cmd) && instances.getSelectedIndex() >= 0){
        	
        	T instance = instances.getSelectedObject();
        	bookmarkBox.addItem(instance);

        }
        else if ("Filter".equals(cmd)){
        }

    }

}

